package com.code.gen.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.core.io.Resource;

import com.code.gen.bean.bo.CodeGenProperties;
import com.code.gen.bean.bo.CodeGenPropertiesSystem;
import com.code.gen.bean.bo.file.CodeGenFieldProperties;
import com.code.gen.bean.bo.file.CodeGenFileProperties;
import com.code.gen.bean.bo.template.CodeGenTemplate;
import com.code.gen.enums.ECodeGenPlaceholder;
import com.code.gen.enums.ECodeGenTemplateQueryType;
import com.code.gen.enums.ECodeGenTemplateType;
import com.code.gen.enums.ECodeGenType;
import com.sojson.enums.core.EGeneralYesNo;
import com.sojson.util.BeanUtil;
import com.sojson.util.ExpUtil;
import com.sojson.util.ReflectUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.file.FileUtil;
import com.sojson.util.properties.PropertiesUtil;
import com.sojson.util.text.Convert;

/**
 * 读取模板类
 * 
 * @author liu
 * @date 2020-08-20
 */
public class CodeGenReadTemplate {

    private CodeGenProperties properties;

    public CodeGenReadTemplate(CodeGenProperties properties) {
        this.properties = properties;
    }

    /**
     * 读取模板文件
     * 
     * @throws Exception
     */
    public void readTemplate() throws Exception {
        // 读取原始模板
        setBaseTemplates();
    }

    /**
     * 读取原始模板
     * 
     * @throws Exception
     */
    private void setBaseTemplates() throws Exception {
        List<Resource> resources = PropertiesUtil.getResources(
            "template/" + properties.getDatabase().getDatabaseEnvironment().getTemplateRootPath() + "/**/*Template");
        ECodeGenTemplateType[] values = ECodeGenTemplateType.values();
        ECodeGenTemplateQueryType[] queryValues = ECodeGenTemplateQueryType.values();
        Map<String, CodeGenTemplate> templates = properties.getTemplates();

        for (Resource resource : resources) {
            CodeGenTemplate template = new CodeGenTemplate();

            InputStream inputStream = null;
            InputStreamReader reader = null;
            BufferedReader buffered = null;
            try {
                inputStream = resource.getInputStream();
                reader = new InputStreamReader(inputStream);
                buffered = new BufferedReader(reader);

                String line = null;
                StringBuilder content = new StringBuilder();
                boolean isBreak = false;
                while ((line = buffered.readLine()) != null) {
                    if (line.contains("~break~")) {
                        isBreak = true;
                    }
                    if (!isBreak) {
                        content.append(line).append("\n");
                    }
                    if (isBreak) {
                        line = line.replace(" ", "");
                        String[] split = line.split("=");
                        if (split.length < 2) {
                            continue;
                        }
                        String key = split[0];

                        if ("id".equals(key)) {
                            template.setId(split[1]);
                        }
                        if ("name".equals(key)) {
                            template.setName(split[1]);
                        }
                        if ("isDbPrefix".equals(key)) {
                            template.setDbPrefix(Convert.toBool(split[1].toLowerCase(), false));
                        }
                        if ("prefix".equals(key)) {
                            template.setPrefix(StringUtil.capitalize(split[1]));
                        }
                        if ("suffix".equals(key)) {
                            template.setSuffix(split[1]);
                        }
                        if ("prefixContent".equals(key)) {
                            template.setPrefixContent(split[1].replace("\\n", "\n").replace("/n", "\n"));
                        }
                        if ("prefixContentOverrides".equals(key)) {
                            template.setPrefixContentOverrides(split[1].replace("\\n", "\n").replace("/n", "\n"));
                        }
                        if ("suffixContent".equals(key)) {
                            template.setSuffixContent(split[1].replace("\\n", "\n").replace("/n", "\n"));
                        }
                        if ("suffixContentOverrides".equals(key)) {
                            template.setSuffixContentOverrides(split[1].replace("\\n", "\n").replace("/n", "\n"));
                        }
                        if ("type".equals(key)) {
                            String val = split[1].toUpperCase();
                            for (ECodeGenTemplateType type : values) {
                                if (type.toString().equals(val)) {
                                    template.setType(type);
                                }
                            }
                        }
                        if ("sort".equals(key)) {
                            template.setSort(Integer.valueOf(split[1]));
                        }
                        if ("queryType".equals(key)) {
                            String val = split[1].toUpperCase();
                            for (ECodeGenTemplateQueryType type : queryValues) {
                                if (type.toString().equals(val)) {
                                    template.setQueryType(type);
                                }
                            }
                        }
                        if ("path".equals(key)) {
                            String replace = split[1].replace(" ", "").replace("\\", ".").replace("/", ".");
                            replace = removeSuffixD(replace);
                            template.setPath(replace.replace(".", "/"));
                        }
                        if ("package".equals(key)) {
                            String replace = split[1].replace(" ", "").replace("\\", ".").replace("/", ".");
                            template.setPackagePath(removeD(replace));
                        }
                        if ("fileName".equals(key)) {
                            template.setFileName(split[1]);
                        }
                        if ("fileNameSuffix".equals(key)) {
                            template.setFileNameSuffix(split[1].toLowerCase());
                        }
                        if ("conditionMethod".equals(key)) {
                            template.setConditionMethod(split[1]);
                        }
                        if ("contentMethod".equals(key)) {
                            template.setContentMethod(split[1]);
                        }
                    }
                }
                if (StringUtil.isBlank(template.getId())) {
                    ExpUtil.throwEx(resource.getFilename() + "模板ID不能为空!");
                }
                if (StringUtil.isBlank(template.getName())) {
                    ExpUtil.throwEx("模板" + template.getId() + "名称不能为空!");
                }
                if (StringUtil.isBlank(template.getType())) {
                    ExpUtil.throwEx("模板" + template.getId() + "类型不能为空!");
                }
                if (template.getType() == ECodeGenTemplateType.MAIN) {
                    String path = template.getPath();
                    if (StringUtil.isBlank(path)) {
                        ExpUtil.throwEx("模板" + template.getId() + "路径不能为空!");
                    }
                    if (FileUtil.isAbsolutePath(path)) {
                        if (StringUtil.isBlank(template.getPackagePath())) {
                            ExpUtil.throwEx("模板" + template.getId() + "当生成路径为绝对路径的时候,包路径不能为空!");
                        }
                    } else {
                        if (StringUtil.isBlank(template.getPackagePath())) {
                            template.setPackagePath(path.replace(FileUtil.CLASSPATH_, "").replace("/", "."));
                        }
                    }
                    if (StringUtil.isBlank(template.getFileName())) {
                        template.setFileName(ECodeGenPlaceholder.CLASS_NAME_D.getPlaceholder());
                    }
                    if (StringUtil.isBlank(template.getFileNameSuffix())) {
                        ExpUtil.throwEx("模板" + template.getId() + "文件名后缀不能为空!");
                    }
                } else {
                    template.setPath(null);
                }
                if (StringUtil.isNotBlank(content)) {
                    template.setContent(content.substring(0, content.length() - 1));
                } else {
                    template.setContent("");
                }
                String key = ECodeGenPlaceholder.PREFIX.getPlaceholder() + template.getId()
                    + ECodeGenPlaceholder.SUFFIX.getPlaceholder();
                if (templates.containsKey(key)) {
                    ExpUtil.throwEx("模板ID" + template.getId() + "已存在!");
                }
                templates.put(key, template);
            } finally {
                FileUtil.closeStream(buffered);
                FileUtil.closeStream(reader);
                FileUtil.closeStream(inputStream);
            }
        }

        // 排序
        List<Entry<String, CodeGenTemplate>> list = new ArrayList<>(properties.getTemplates().entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, CodeGenTemplate>>() {
            @Override
            public int compare(Entry<String, CodeGenTemplate> o1, Entry<String, CodeGenTemplate> o2) {
                return o1.getValue().getSort() - o2.getValue().getSort();
            }
        });
        Map<String, CodeGenTemplate> linkedHashMap = new LinkedHashMap<>();
        for (Entry<String, CodeGenTemplate> e : list) {
            linkedHashMap.put(e.getKey(), e.getValue());
        }
        properties.setTemplates(linkedHashMap);
    }

    /**
     * 初始化文件生成路径
     */
    public void initGeneratePackagePath(CodeGenFileProperties file) {
        // 初始化模板路径
        Map<String, CodeGenTemplate> contents = properties.getContents();
        for (CodeGenTemplate content : contents.values()) {
            String packagePath = content.getPackagePath();
            if (packagePath == null) {
                continue;
            }

            packagePath = packagePath.replace(ECodeGenPlaceholder.BASE_PATH.getPlaceholder(), file.getPackageName());
            packagePath = packagePath.replace(ECodeGenPlaceholder.MODULE_PATH.getPlaceholder(), file.getModuleName());
            packagePath = packagePath.replace(ECodeGenPlaceholder.BASE_MODULE_PATH.getPlaceholder(),
                file.getPackageName() + "." + file.getModuleName());
            content.setPackagePath(packagePath);
        }
    }

    /**
     * 初始化文件生成路径
     */
    public void initGeneratePath(CodeGenFileProperties file) {
        // 初始化模板路径
        Map<String, CodeGenTemplate> contents = properties.getContents();
        for (CodeGenTemplate content : contents.values()) {
            String path = content.getPath();
            if (path == null) {
                continue;
            }

            String classpath = null;

            // 模板设置生成路径
            Integer genType = file.getGenType();
            if (ECodeGenType.PATH.getCode() == genType) {
                if (FileUtil.isAbsolutePath(file.getGenPath())) {
                    content.setPathIsAbsolute(true);
                    if (path.startsWith(FileUtil.CLASSPATH_)) {
                        path = path.replace(FileUtil.CLASSPATH_, file.getGenPath() + "/");
                    }
                    if (file.getGenPath().startsWith(FileUtil.CLASSPATH_)) {
                        classpath = FileUtil.CLASSPATH_;
                        file.setGenPath(file.getGenPath().replace(FileUtil.CLASSPATH_, ""));
                        content.setPathIsClasspath(true);
                    } else {
                        content.setPathIsClasspath(false);
                    }
                } else {
                    content.setPathIsAbsolute(false);
                    if (path.startsWith(FileUtil.CLASSPATH_)) {
                        classpath = FileUtil.CLASSPATH_;
                        path = path.replace(FileUtil.CLASSPATH_, "");
                        content.setPathIsClasspath(true);
                    } else {
                        content.setPathIsClasspath(false);
                    }
                }
                path =
                    path.replace(ECodeGenPlaceholder.BASE_PATH.getPlaceholder(), file.getGenPath().replace(".", "/"));
                path = path.replace(ECodeGenPlaceholder.MODULE_PATH.getPlaceholder(),
                    file.getModuleName().replace(".", "/"));
                path = path.replace(ECodeGenPlaceholder.BASE_MODULE_PATH.getPlaceholder(),
                    file.getGenPath().replace(".", "/") + "/" + file.getModuleName().replace(".", "/"));
                path = path.replace("//", "/");
            } else {
                if (path.startsWith(FileUtil.CLASSPATH_)) {
                    classpath = FileUtil.CLASSPATH_;
                    path = path.substring(classpath.length());
                    content.setPathIsClasspath(true);
                } else {
                    content.setPathIsClasspath(false);
                }

                path = path.replace(ECodeGenPlaceholder.BASE_PATH.getPlaceholder(),
                    file.getPackageName().replace(".", "/"));
                path = path.replace(ECodeGenPlaceholder.MODULE_PATH.getPlaceholder(),
                    file.getModuleName().replace(".", "/"));
                path = path.replace(ECodeGenPlaceholder.BASE_MODULE_PATH.getPlaceholder(),
                    file.getPackageName().replace(".", "/") + "/" + file.getModuleName().replace(".", "/"));
                if (FileUtil.isAbsolutePath(path)) {
                    content.setPathIsAbsolute(true);
                } else {
                    content.setPathIsAbsolute(false);
                }
            }
            content.setPath(path);
        }
    }

    /**
     * 删除路径后面的.
     * 
     * @param path
     * @return
     */
    private static String removeSuffixD(String path) {
        String d = ".";
        String dd = "..";
        if (path.contains(dd)) {
            return removeSuffixD(path.replace(dd, d));
        }
        if (path.contains(FileUtil.CLASSPATH_ + d)) {
            return removeSuffixD(path.replace(FileUtil.CLASSPATH_ + d, FileUtil.CLASSPATH_));
        }
        if (path.endsWith(d)) {
            return removeSuffixD(path.substring(0, path.length() - 1));
        }
        return path;
    }

    /**
     * 合并模板
     * 
     * @param file
     */
    public void merged(CodeGenFileProperties file) {
        // 给字段类型的模板赋值
        Map<String, CodeGenTemplate> templates = properties.getTemplates();
        for (String id : templates.keySet()) {
            CodeGenTemplate template = templates.get(id);
            if (StringUtil.isNotBlank(template.getConditionMethod()) && !conditionMethod(file, template)) {
                // 复制模板的备份模板
                CodeGenTemplate copy = new CodeGenTemplate();
                BeanUtil.copyBeanProp(copy, template);
                copy.setContent("");
                properties.getContents().put(id, copy);
            } else if (ECodeGenTemplateType.FIELD == template.getType()) {
                ECodeGenTemplateQueryType queryType = template.getQueryType();
                if (ECodeGenTemplateQueryType.QUERY == queryType) {
                    addQueryField(id, template, file);
                } else if (ECodeGenTemplateQueryType.RESULT == queryType) {
                    addResultField(id, template, file);
                } else {
                    addField(id, template, file);
                }
                if (StringUtil.isBlank(template.getContent())) {
                    properties.getContents().get(id).setContent("");
                }
            } else if (StringUtil.isNotBlank(template.getContentMethod())) {
                // 读取动态模板
                CodeGenTemplate copy = new CodeGenTemplate();
                BeanUtil.copyBeanProp(copy, template);
                copy.setContent(contentMethod(file, template));
                properties.getContents().put(id, copy);
            } else {
                // 复制模板的备份模板
                CodeGenTemplate copy = new CodeGenTemplate();
                BeanUtil.copyBeanProp(copy, template);
                properties.getContents().put(id, copy);
            }
            CodeGenTemplate codeGenTemplate = properties.getContents().get(id);
            String content = codeGenTemplate.getContent();
            String prefixContent = codeGenTemplate.getPrefixContent();
            String prefixContentOverrides = codeGenTemplate.getPrefixContentOverrides();
            String suffixContent = codeGenTemplate.getSuffixContent();
            String suffixContentOverrides = codeGenTemplate.getSuffixContentOverrides();
            if (StringUtil.isNotBlank(content)) {
                if (prefixContentOverrides != null && content.startsWith(prefixContentOverrides)) {
                    content = content.substring(prefixContentOverrides.length());
                }
                if (suffixContentOverrides != null && content.endsWith(suffixContentOverrides)) {
                    content = content.substring(0, content.length() - suffixContentOverrides.length());
                }
                if (prefixContent != null) {
                    content = prefixContent + content;
                }
                if (suffixContent != null) {
                    content = content + suffixContent;
                }
            }
            codeGenTemplate.setContent(content);
        }

        // 初始化包路径
        new CodeGenReadTemplate(properties).initGeneratePackagePath(file);

        // 初始化模板占位符
        Map<String, String> placeholders = properties.getPlaceholders();
        Map<String, CodeGenTemplate> contents = properties.getContents();
        String prefix = ECodeGenPlaceholder.PREFIX.getPlaceholder();
        Collection<CodeGenTemplate> values = contents.values();
        for (CodeGenTemplate template : values) {
            String id = template.getId();
            if (template.getType() == ECodeGenTemplateType.MAIN) {
                placeholders.put(prefix + id + ECodeGenPlaceholder._SUFFIX_PACKAGE_PATH.getPlaceholder(),
                    template.getPackagePath());
            }
        }

        // 替换占位符
        for (CodeGenTemplate template : contents.values()) {
            String fileName = template.getFileName();
            String content = template.getContent();
            for (Entry<String, String> placeholder : placeholders.entrySet()) {
                String value = placeholder.getValue();
                if (value != null) {
                    if (template.getType() == ECodeGenTemplateType.MAIN) {
                        fileName = fileName.replace(placeholder.getKey(), placeholder.getValue());
                    }

                    content = content.replace(placeholder.getKey(), placeholder.getValue());
                }
            }
            template.setFileName(fileName);
            template.setContent(content);
        }

        // 合并模板
        merged();
    }

    /**
     * 判断模板是否可以使用
     * 
     * @param file
     * @param template
     * @return
     */
    private boolean conditionMethod(CodeGenFileProperties file, CodeGenTemplate template) {
        boolean not = false;
        String conditionMethod = template.getConditionMethod();
        String t = "!";
        if (conditionMethod.startsWith(t)) {
            conditionMethod = conditionMethod.substring(1);
            template.setConditionMethod(conditionMethod);
            conditionMethod = "!" + conditionMethod;
            not = true;
        }
        Object invokeMethod = ReflectUtil.invokeMethodByName(new CodeGenConditionMethodUtil(properties, file, template),
            template.getConditionMethod(), new Object[0]);
        template.setConditionMethod(conditionMethod);
        return not ? !((boolean)invokeMethod) : (boolean)invokeMethod;
    }

    /**
     * 读取动态模板
     * 
     * @param file
     * @param template
     * @return
     */
    private String contentMethod(CodeGenFileProperties file, CodeGenTemplate template) {
        Object invokeMethod = ReflectUtil.invokeMethodByName(new CodeGenConditionMethodUtil(properties, file, template),
            template.getContentMethod(), new Object[0]);
        return invokeMethod.toString();
    }

    /**
     * 合并模板
     * 
     * @param file
     */
    private void merged() {
        // 先合并包模板
        Map<String, CodeGenTemplate> contents = properties.getContents();
        Set<String> ids = contents.keySet();

        for (CodeGenTemplate template : contents.values()) {
            if (template.getType() == ECodeGenTemplateType.PACKAGE) {
                merged(template, contents, ids);
                template.setContent(sortPackage(template.getContent()));
            }
        }
        // 替换模板占位符
        for (CodeGenTemplate template : contents.values()) {
            merged(template, contents, ids);
        }
    }

    /**
     * 合并模板
     * 
     * @param template
     * @param templates
     * @param ids
     */
    private void merged(CodeGenTemplate template, Map<String, CodeGenTemplate> templates, Set<String> ids) {
        String content = template.getContent();
        boolean exists = false;
        for (String id : ids) {
            if (content.contains(id)) {
                exists = true;
                content = content.replace(id, templates.get(id).getContent());
                template.setContent(content);
            }
        }
        if (exists) {
            merged(template, templates, ids);
        }
    }

    /**
     * 给字段类型的模板赋值
     * 
     * @param file
     */
    private void addField(String id, CodeGenTemplate template, CodeGenFileProperties file) {
        String content = template.getContent();
        StringBuilder builder = new StringBuilder();
        List<String> noFields = properties.getSystem().getNoFields();

        List<CodeGenFieldProperties> fields = file.getFileFeild();
        for (CodeGenFieldProperties field : fields) {
            if (noFields.contains(field.getFieldNameDatabaseD())) {
                continue;
            }
            builder.append(replacePropertyPlaceholder(content, field)).append("\n");
        }

        CodeGenTemplate copy = new CodeGenTemplate();
        BeanUtil.copyBeanProp(copy, template);
        if (builder.length() > 0) {
            copy.setContent(builder.toString());
        } else {
            copy.setContent("");
        }
        properties.getContents().put(id, copy);
    }

    /**
     * 给查询字段类型的模板赋值
     * 
     * @param file
     */
    private void addQueryField(String id, CodeGenTemplate template, CodeGenFileProperties file) {
        String content = template.getContent();
        StringBuilder builder = new StringBuilder();
        CodeGenPropertiesSystem system = properties.getSystem();
        List<String> queryFields = system.getQueryFields();
        List<String> queryNoFields = system.getQueryNoFields();

        List<CodeGenFieldProperties> fields = file.getFileFeild();
        for (CodeGenFieldProperties field : fields) {
            if (queryFields.size() > 0) {
                if (!queryFields.contains(field.getFieldNameDatabaseD())) {
                    continue;
                }
            } else if (queryNoFields.size() > 0) {
                if (queryNoFields.contains(field.getFieldNameDatabaseD())) {
                    continue;
                }
            } else {

            }
            builder.append(replacePropertyPlaceholder(content, field)).append("\n");
        }

        CodeGenTemplate copy = new CodeGenTemplate();
        BeanUtil.copyBeanProp(copy, template);
        if (builder.length() > 0) {
            copy.setContent(builder.toString());
        } else {
            copy.setContent("");
        }
        properties.getContents().put(id, copy);
    }

    /**
     * 给返回字段类型的模板赋值
     * 
     * @param file
     */
    private void addResultField(String id, CodeGenTemplate template, CodeGenFileProperties file) {
        String content = template.getContent();
        StringBuilder builder = new StringBuilder();
        CodeGenPropertiesSystem system = properties.getSystem();
        List<String> resultFields = system.getResultFields();
        List<String> resultNoFields = system.getResultNoFields();

        List<CodeGenFieldProperties> fields = file.getFileFeild();
        for (CodeGenFieldProperties field : fields) {
            if (resultFields.size() > 0) {
                if (!resultFields.contains(field.getFieldNameDatabaseD())) {
                    continue;
                }
            } else if (resultNoFields.size() > 0) {
                if (resultNoFields.contains(field.getFieldNameDatabaseD())) {
                    continue;
                }
            } else {

            }
            builder.append(replacePropertyPlaceholder(content, field)).append("\n");
        }

        CodeGenTemplate copy = new CodeGenTemplate();
        BeanUtil.copyBeanProp(copy, template);
        if (builder.length() > 0) {
            copy.setContent(builder.toString());
        } else {
            copy.setContent("");
        }
        properties.getContents().put(id, copy);
    }

    /**
     * 对包排序
     * 
     * @param packages
     * @return
     */
    private String sortPackage(String packages) {
        if (StringUtil.isBlank(packages)) {
            return packages;
        }

        String[] split = packages.split("\n");
        String sortPackage = sortPackage(new HashSet<>(Arrays.asList(split)));
        if (StringUtil.isBlank(sortPackage)) {
            return sortPackage;
        }
        return "\n" + sortPackage + "\n";
    }

    /**
     * 对包排序
     * 
     * @param packages
     * @return
     */
    private String sortPackage(Set<String> packages) {
        CodeGenPropertiesSystem system = properties.getSystem();

        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder assign = new StringBuilder();
        StringBuilder other = new StringBuilder();
        Map<String, List<String>> assignMap = new HashMap<>(20);
        List<String> otherList = new ArrayList<>();

        // 指定的包添加并排序
        for (String sort : system.getImportSort()) {
            for (String pak : packages) {
                String copy = pak;
                if (copy.startsWith("import")) {
                    copy = copy.substring("import".length()).trim();
                }
                if (copy.substring(0, copy.indexOf(".") >= 0 ? copy.indexOf(".") : copy.length()).equals(sort)) {
                    List<String> list = assignMap.get(sort);
                    if (list == null) {
                        list = new ArrayList<>();
                        assignMap.put(sort, list);
                    }
                    list.add(pak);
                }
            }
        }
        for (String sort : system.getImportSort()) {
            List<String> list = assignMap.get(sort);
            if (list != null && list.size() > 0) {
                assign.append(sortPackage(list)).append("\n");
                if (system.isImportSortSpacing()) {
                    assign.append("\n");
                }
            }
        }
        if (assignMap.size() > 0) {
            assign = new StringBuilder(assign.substring(0, assign.length() - (system.isImportSortSpacing() ? 2 : 1)));
        }

        // 其他包添加并排序
        for (String pak : packages) {
            // 标记是否在集合中
            boolean is = false;
            String copy = pak;
            if (copy.startsWith("import")) {
                copy = copy.substring("import".length()).trim();
            }
            for (String sort : system.getImportSort()) {
                if (copy.substring(0, copy.indexOf(".") >= 0 ? copy.indexOf(".") : copy.length()).equals(sort)) {
                    is = true;
                    break;
                }
            }
            if (!is && !"".equals(copy.trim())) {
                otherList.add(pak);
            }
        }
        other.append(sortPackage(otherList));

        if (system.isImportSortOther()) {
            if (StringUtil.isNotBlank(other)) {
                stringBuilder.append(other);
                if (StringUtil.isNotBlank(assign)) {
                    stringBuilder.append("\n");
                }
            }
            if (StringUtil.isNotBlank(assign)) {
                if (StringUtil.isNotBlank(other)) {
                    if (system.isImportSortSpacing()) {
                        stringBuilder.append("\n");
                    }
                }
                stringBuilder.append(assign);
            }
        } else {
            if (StringUtil.isNotBlank(assign)) {
                stringBuilder.append(assign);
                if (StringUtil.isNotBlank(other)) {
                    stringBuilder.append("\n");
                }
            }
            if (StringUtil.isNotBlank(other)) {
                if (StringUtil.isNotBlank(assign)) {
                    if (system.isImportSortSpacing()) {
                        stringBuilder.append("\n");
                    }
                }
                stringBuilder.append(other);
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 对包排序
     * 
     * @param packages
     * @return
     */
    private String sortPackage(List<String> packages) {
        if (packages.size() < 1) {
            return "";
        }
        for (int i = 0; i < packages.size() - 1; i++) {
            for (int j = 0; j < packages.size() - i - 1; j++) {
                if (packages.get(j).compareTo(packages.get(j + 1)) > 0) {
                    String strI = packages.get(j);
                    packages.set(j, packages.get(j + 1));
                    packages.set(j + 1, strI);
                }
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String string : packages) {
            stringBuilder.append(string + "\n");
        }
        stringBuilder.replace(stringBuilder.lastIndexOf("\n"), stringBuilder.length(), "");
        String string = stringBuilder.toString();
        if (StringUtil.isBlank(string)) {
            return string;
        }
        return string;
    }

    /**
     * 给模板替换属性占位符
     * 
     * @param fileTemplate
     * @param filePropertie
     * @return
     */
    public static String replacePropertyPlaceholder(String fileTemplate, CodeGenFieldProperties filePropertie) {
        String fieldComment = filePropertie.getFieldComment();
        if (fieldComment == null) {
            fieldComment = "";
        }

        // Bean对象属性
        fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_COMMENT.getPlaceholder(), fieldComment);
        if (EGeneralYesNo.YES.getCode() == filePropertie.getIsList()) {
            fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_EXCEL.getPlaceholder(),
                StringUtil.ENTER + "    @Excel(name = \"" + fieldComment + "\")");
        } else {
            fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_EXCEL.getPlaceholder(), "");
        }
        fileTemplate =
            fileTemplate.replace(ECodeGenPlaceholder.FIELD_NAME_X.getPlaceholder(), filePropertie.getFieldNameX());
        fileTemplate =
            fileTemplate.replace(ECodeGenPlaceholder.FIELD_NAME_D.getPlaceholder(), filePropertie.getFieldNameD());
        fileTemplate =
            fileTemplate.replace(ECodeGenPlaceholder.FIELD_TYPE.getPlaceholder(), filePropertie.getFieldJavaType());
        fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_NAME_DB_D.getPlaceholder(),
            filePropertie.getFieldNameDatabaseD());
        fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_TYPE_DB.getPlaceholder(),
            filePropertie.getFieldDatabaseType());
        fileTemplate = fileTemplate.replace(ECodeGenPlaceholder.FIELD_TYPE_DB_XML.getPlaceholder(),
            filePropertie.getFieldXmlType());

        return fileTemplate;
    }

    /**
     * 删除路径前面和后面的.
     * 
     * @param path
     * @return
     */
    public static String removeD(String path) {
        String d = ".";
        String dd = "..";
        if (path.contains(dd)) {
            return removeSuffixD(path.replace(dd, d));
        }
        if (path.startsWith(d)) {
            return removeD(path.substring(1, path.length()));
        }
        if (path.endsWith(d)) {
            return removeD(path.substring(0, path.length() - 1));
        }
        return path;
    }

}